﻿#include "WidgetPipelines.h"
#include "Render/VulkanContext.h"
#include "Render/Material/VulkanShaders.h"
#include "Render/Material/VulkanShader.h"


void SWidgetPipelines::Init()
{

    CreateCircleWidgetPipeline();
    CreateRingWidgetPipeline();

    //create Line item things
    {
        //Line item have a start point and a end point and a color

        //create pipeline layout
        TVector<vk::PushConstantRange> PushConstantRanges=
        {
            vk::PushConstantRange()
            .setStageFlags(vk::ShaderStageFlagBits::eVertex)
            .setOffset(0)
            .setSize(sizeof(SLineItemVertexPushConstant))
        };

        TVector<vk::DescriptorSetLayout> PipelineDesLayouts={CVulkanContext::Get()->GetImageWidgetDescriptorSetLayout().Layout};

        vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo()
            .setSetLayouts(PipelineDesLayouts)
            .setPushConstantRanges(PushConstantRanges);

        CanvasWidgetLinePipelineLayout =CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);
        
        //create pipeline
        auto VertexShader=CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"CanvasWidgetLineVertex");
        auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"CanvasWidgetLineFragment");

        //dynamic state
        vk::DynamicState DynamicState[]={
            vk::DynamicState::eViewport
            ,vk::DynamicState::eScissor
            ,vk::DynamicState::eLineWidth
        };

        vk::PipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo=vk::PipelineDynamicStateCreateInfo()
            .setDynamicStateCount(3)
            .setPDynamicStates(DynamicState);

        vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2];
        PipelineShaderStageCreateInfo[0]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main");

        PipelineShaderStageCreateInfo[1]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eFragment)
            .setModule(FragmentShader->Module)
            .setPName("main");

        vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
            .setVertexBindingDescriptionCount(0)
            .setVertexAttributeDescriptionCount(0);

        vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo=vk::PipelineInputAssemblyStateCreateInfo()
            .setTopology(vk::PrimitiveTopology::eLineList);

        vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
            .setViewportCount(1)
            .setScissorCount(1);

        vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
            .setPolygonMode(vk::PolygonMode::eFill)
            .setCullMode(vk::CullModeFlagBits::eNone)
            .setFrontFace(vk::FrontFace::eClockwise)
            .setLineWidth(1.0f);

        vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
            .setRasterizationSamples(vk::SampleCountFlagBits::e1);

        vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
            .setDepthTestEnable(true)
            .setDepthWriteEnable(true)
            .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
            .setDepthBoundsTestEnable(false)
            .setStencilTestEnable(false);

        vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
            
                .setColorWriteMask(
                    vk::ColorComponentFlagBits::eR
                    |vk::ColorComponentFlagBits::eG
                    |vk::ColorComponentFlagBits::eB
                    |vk::ColorComponentFlagBits::eA
                )
                .setBlendEnable(true) //color might be transparent
                .setSrcColorBlendFactor(vk::BlendFactor::eSrcAlpha)
                .setDstColorBlendFactor(vk::BlendFactor::eOneMinusSrcAlpha)
                .setColorBlendOp(vk::BlendOp::eAdd)
                .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
                .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
                .setAlphaBlendOp(vk::BlendOp::eAdd)
                ;

        vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
            .setAttachmentCount(1)
            .setPAttachments(&PipelineColorBlendAttachmentState);

        vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
            .setPDynamicState(&PipelineDynamicStateCreateInfo)
            .setStageCount(2)
            .setPStages(PipelineShaderStageCreateInfo)
            .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
            .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
            .setPViewportState(&PipelineViewportStateCreateInfo)
            .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
            .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
            .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
            .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
            .setLayout(CanvasWidgetLinePipelineLayout)
            .setRenderPass(CVulkanContext::Get()->GetWidgetRenderPass())
            .setSubpass(0);

        CanvasWidgetLinePipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;
    }
    
    //create triangle item things
    {
        //create pipeline layout
        TVector<vk::PushConstantRange> PushConstantRanges=
        {
            vk::PushConstantRange()
            .setStageFlags(vk::ShaderStageFlagBits::eVertex)
            .setOffset(0)
            .setSize(sizeof(STriangleItemVertexPushConstant))
        };

        TVector<vk::DescriptorSetLayout> PipelineDesLayouts={CVulkanContext::Get()->GetImageWidgetDescriptorSetLayout().Layout};
        vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo()
            .setSetLayouts(PipelineDesLayouts)
            .setPushConstantRanges(PushConstantRanges);
        

        CanvasWidgetTrianglePipelineLayout =CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);

        //create pipeline
        auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"CanvasWidgetTriangleVertex");
        auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"CanvasWidgetTriangleFragment");

        //dynamic state
        vk::DynamicState DynamicState[2]={vk::DynamicState::eViewport,vk::DynamicState::eScissor};

        vk::PipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo=vk::PipelineDynamicStateCreateInfo()
            .setDynamicStateCount(2)
            .setPDynamicStates(DynamicState);

        vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2];
        PipelineShaderStageCreateInfo[0]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main");

        PipelineShaderStageCreateInfo[1]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eFragment)
            .setModule(FragmentShader->Module)
            .setPName("main");

        vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
            .setVertexBindingDescriptionCount(0)
            .setVertexAttributeDescriptionCount(0);

        vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo=vk::PipelineInputAssemblyStateCreateInfo()
            .setTopology(vk::PrimitiveTopology::eTriangleList);

        vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
            .setViewportCount(1)
            .setScissorCount(1);

        vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
            .setPolygonMode(vk::PolygonMode::eFill)
            .setCullMode(vk::CullModeFlagBits::eNone)
            .setFrontFace(vk::FrontFace::eClockwise)
            .setLineWidth(1.0f);

        vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
            .setRasterizationSamples(vk::SampleCountFlagBits::e1);

        vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
            .setDepthTestEnable(true)
            .setDepthWriteEnable(true)
            .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
            .setDepthBoundsTestEnable(false)
            .setStencilTestEnable(false);

        vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
            
                .setColorWriteMask(
                    vk::ColorComponentFlagBits::eR
                    |vk::ColorComponentFlagBits::eG
                    |vk::ColorComponentFlagBits::eB
                    |vk::ColorComponentFlagBits::eA
                )
                .setBlendEnable(true) //color might be transparent
                .setSrcColorBlendFactor(vk::BlendFactor::eSrcAlpha)
                .setDstColorBlendFactor(vk::BlendFactor::eOneMinusSrcAlpha)
                .setColorBlendOp(vk::BlendOp::eAdd)
                .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
                .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
                .setAlphaBlendOp(vk::BlendOp::eAdd)
                ;

        vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
            .setAttachmentCount(1)
            .setPAttachments(&PipelineColorBlendAttachmentState);

        vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
            .setPDynamicState(&PipelineDynamicStateCreateInfo)
            .setStageCount(2)
            .setPStages(PipelineShaderStageCreateInfo)
            .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
            .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
            .setPViewportState(&PipelineViewportStateCreateInfo)
            .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
            .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
            .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
            .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
            .setLayout(CanvasWidgetTrianglePipelineLayout)
            .setRenderPass(CVulkanContext::Get()->GetWidgetRenderPass())
            .setSubpass(0);

        CanvasWidgetTrianglePipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;
    }    

    //create image item things
    {
        //create pipeline layout
        TVector<vk::PushConstantRange> PushConstantRanges=
        {
            vk::PushConstantRange()
            .setStageFlags(vk::ShaderStageFlagBits::eVertex)
            .setOffset(0)
            .setSize(sizeof(SImageItemVertexPushConstant))
        };

        TVector<vk::DescriptorSetLayout> PipelineDesLayouts={CVulkanContext::Get()->GetImageWidgetDescriptorSetLayout().Layout};
        vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo()
            .setSetLayouts(PipelineDesLayouts)
            .setPushConstantRanges(PushConstantRanges);
        

        CanvasWidgetImagePipelineLayout =CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);

        //create pipeline
        auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"CanvasWidgetImage_vert");
        auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"CanvasWidgetImage_frag");

        //dynamic state
        vk::DynamicState DynamicState[2]={vk::DynamicState::eViewport,vk::DynamicState::eScissor};

        vk::PipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo=vk::PipelineDynamicStateCreateInfo()
            .setDynamicStateCount(2)
            .setPDynamicStates(DynamicState);

        vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2];
        PipelineShaderStageCreateInfo[0]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main");

        PipelineShaderStageCreateInfo[1]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eFragment)
            .setModule(FragmentShader->Module)
            .setPName("main");

        vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
            .setVertexBindingDescriptionCount(0)
            .setVertexAttributeDescriptionCount(0);

        vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo
            =vk::PipelineInputAssemblyStateCreateInfo()
            .setTopology(vk::PrimitiveTopology::eTriangleStrip);

        vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
            .setViewportCount(1)
            .setScissorCount(1);

        vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
            .setPolygonMode(vk::PolygonMode::eFill)
            .setCullMode(vk::CullModeFlagBits::eNone)
            .setFrontFace(vk::FrontFace::eClockwise)
            .setLineWidth(1.0f);

        vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
            .setRasterizationSamples(vk::SampleCountFlagBits::e1);

        vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
            .setDepthTestEnable(true)
            .setDepthWriteEnable(true)
            .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
            .setDepthBoundsTestEnable(false)
            .setStencilTestEnable(false);

        vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
            
                .setColorWriteMask(
                    vk::ColorComponentFlagBits::eR
                    |vk::ColorComponentFlagBits::eG
                    |vk::ColorComponentFlagBits::eB
                    |vk::ColorComponentFlagBits::eA
                )
                .setBlendEnable(true) //color might be transparent
                .setSrcColorBlendFactor(vk::BlendFactor::eSrcAlpha)
                .setDstColorBlendFactor(vk::BlendFactor::eOneMinusSrcAlpha)
                .setColorBlendOp(vk::BlendOp::eAdd)
                .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
                .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
                .setAlphaBlendOp(vk::BlendOp::eAdd)
                ;

        vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
            .setAttachmentCount(1)
            .setPAttachments(&PipelineColorBlendAttachmentState);

        vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
            .setPDynamicState(&PipelineDynamicStateCreateInfo)
            .setStageCount(2)
            .setPStages(PipelineShaderStageCreateInfo)
            .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
            .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
            .setPViewportState(&PipelineViewportStateCreateInfo)
            .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
            .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
            .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
            .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
            .setLayout(CanvasWidgetImagePipelineLayout)
            .setRenderPass(CVulkanContext::Get()->GetWidgetRenderPass())
            .setSubpass(0);

        CanvasWidgetImagePipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;

    }

//create text item things
    {
        //create pipeline layout
        TVector<vk::PushConstantRange> PushConstantRanges=
        {
            vk::PushConstantRange()
            .setStageFlags(vk::ShaderStageFlagBits::eVertex)
            .setOffset(0)
            .setSize(sizeof(STextItemVertexPushConstant))
        };

        TVector<vk::DescriptorSetLayout> PipelineDesLayouts={CVulkanContext::Get()->GetImageWidgetDescriptorSetLayout().Layout};
        vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo()
            .setSetLayouts(PipelineDesLayouts)
            .setPushConstantRanges(PushConstantRanges);
        

        CanvasWidgetTextPipelineLayout =CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);

        //create pipeline
        auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"CanvasWidgetTextImage_vert");
        auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"CanvasWidgetTextImage_frag");

        //dynamic state
        vk::DynamicState DynamicState[2]={vk::DynamicState::eViewport,vk::DynamicState::eScissor};

        vk::PipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo=vk::PipelineDynamicStateCreateInfo()
            .setDynamicStateCount(2)
            .setPDynamicStates(DynamicState);

        vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2];
        PipelineShaderStageCreateInfo[0]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main");

        PipelineShaderStageCreateInfo[1]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eFragment)
            .setModule(FragmentShader->Module)
            .setPName("main");

        vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
            .setVertexBindingDescriptionCount(0)
            .setVertexAttributeDescriptionCount(0);

        vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo
            =vk::PipelineInputAssemblyStateCreateInfo()
            .setTopology(vk::PrimitiveTopology::eTriangleStrip);

        vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
            .setViewportCount(1)
            .setScissorCount(1);

        vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
            .setPolygonMode(vk::PolygonMode::eFill)
            .setCullMode(vk::CullModeFlagBits::eNone)
            .setFrontFace(vk::FrontFace::eClockwise)
            .setLineWidth(1.0f);

        vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
            .setRasterizationSamples(vk::SampleCountFlagBits::e1);

        vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
            .setDepthTestEnable(true)
            .setDepthWriteEnable(true)
            .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
            .setDepthBoundsTestEnable(false)
            .setStencilTestEnable(false);

        vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
            
                .setColorWriteMask(
                    vk::ColorComponentFlagBits::eR
                    |vk::ColorComponentFlagBits::eG
                    |vk::ColorComponentFlagBits::eB
                    |vk::ColorComponentFlagBits::eA
                )
                .setBlendEnable(true) //color might be transparent
                .setSrcColorBlendFactor(vk::BlendFactor::eSrcAlpha)
                .setDstColorBlendFactor(vk::BlendFactor::eOneMinusSrcAlpha)
                .setColorBlendOp(vk::BlendOp::eAdd)
                .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
                .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
                .setAlphaBlendOp(vk::BlendOp::eAdd)
                ;

        vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
            .setAttachmentCount(1)
            .setPAttachments(&PipelineColorBlendAttachmentState);

        vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
            .setPDynamicState(&PipelineDynamicStateCreateInfo)
            .setStageCount(2)
            .setPStages(PipelineShaderStageCreateInfo)
            .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
            .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
            .setPViewportState(&PipelineViewportStateCreateInfo)
            .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
            .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
            .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
            .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
            .setLayout(CanvasWidgetTextPipelineLayout)
            .setRenderPass(CVulkanContext::Get()->GetWidgetRenderPass())
            .setSubpass(0);

        CanvasWidgetTextPipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;

    }


    //create circle item things
    {
        //create pipeline layout
        TVector<vk::PushConstantRange> PushConstantRanges=
        {
            vk::PushConstantRange()
            .setStageFlags(vk::ShaderStageFlagBits::eVertex)
            .setOffset(0)
            .setSize(sizeof(SCircleItemVertexPushConstant))
        };

        TVector<vk::DescriptorSetLayout> PipelineDesLayouts={CVulkanContext::Get()->GetImageWidgetDescriptorSetLayout().Layout};
        vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo()
            .setSetLayouts(PipelineDesLayouts)
            .setPushConstantRanges(PushConstantRanges);
        

        CanvasWidgetCirclePipelineLayout =CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);

        //create pipeline
        auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"CanvasWidgetCircle_vert");
        auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"CanvasWidgetCircle_frag");

        //dynamic state
        vk::DynamicState DynamicState[2]={vk::DynamicState::eViewport,vk::DynamicState::eScissor};

        vk::PipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo=vk::PipelineDynamicStateCreateInfo()
            .setDynamicStateCount(2)
            .setPDynamicStates(DynamicState);

        vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2];
        PipelineShaderStageCreateInfo[0]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eVertex)
            .setModule(VertexShader->Module)
            .setPName("main");

        PipelineShaderStageCreateInfo[1]=vk::PipelineShaderStageCreateInfo()
            .setStage(vk::ShaderStageFlagBits::eFragment)
            .setModule(FragmentShader->Module)
            .setPName("main");

        vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
            .setVertexBindingDescriptionCount(0)
            .setVertexAttributeDescriptionCount(0);

        vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo
            =vk::PipelineInputAssemblyStateCreateInfo()
            .setTopology(vk::PrimitiveTopology::eTriangleStrip);

        vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
            .setViewportCount(1)
            .setScissorCount(1);

        vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
            .setPolygonMode(vk::PolygonMode::eFill)
            .setCullMode(vk::CullModeFlagBits::eNone)
            .setFrontFace(vk::FrontFace::eClockwise)
            .setLineWidth(1.0f);

        vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
            .setRasterizationSamples(vk::SampleCountFlagBits::e1);

        vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
            .setDepthTestEnable(true)
            .setDepthWriteEnable(true)
            .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
            .setDepthBoundsTestEnable(false)
            .setStencilTestEnable(false);

        vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
            
                .setColorWriteMask(
                    vk::ColorComponentFlagBits::eR
                    |vk::ColorComponentFlagBits::eG
                    |vk::ColorComponentFlagBits::eB
                    |vk::ColorComponentFlagBits::eA
                )
                .setBlendEnable(true) //color might be transparent
                .setSrcColorBlendFactor(vk::BlendFactor::eSrcAlpha)
                .setDstColorBlendFactor(vk::BlendFactor::eOneMinusSrcAlpha)
                .setColorBlendOp(vk::BlendOp::eAdd)
                .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
                .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
                .setAlphaBlendOp(vk::BlendOp::eAdd)
                ;

        vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
            .setAttachmentCount(1)
            .setPAttachments(&PipelineColorBlendAttachmentState);

        vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
            .setPDynamicState(&PipelineDynamicStateCreateInfo)
            .setStageCount(2)
            .setPStages(PipelineShaderStageCreateInfo)
            .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
            .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
            .setPViewportState(&PipelineViewportStateCreateInfo)
            .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
            .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
            .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
            .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
            .setLayout(CanvasWidgetCirclePipelineLayout)
            .setRenderPass(CVulkanContext::Get()->GetWidgetRenderPass())
            .setSubpass(0);

        CanvasWidgetCirclePipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;

    }

}

void SWidgetPipelines::CreateCircleWidgetPipeline()
{
    //create pipeline layout
    TVector<vk::PushConstantRange> PushConstantRanges=
    {
        vk::PushConstantRange()
        .setStageFlags(vk::ShaderStageFlagBits::eVertex)
        .setOffset(0)
        .setSize(sizeof(SCircleItemVertexPushConstant))
    };

    TVector<vk::DescriptorSetLayout> PipelineDesLayouts={CVulkanContext::Get()->GetImageWidgetDescriptorSetLayout().Layout};
    vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo()
        .setSetLayouts(PipelineDesLayouts)
        .setPushConstantRanges(PushConstantRanges);
    

    CircleWidgetPipelineLayout =CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);

    //create pipeline
    auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"CircleWidget_vert");
    auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"CircleWidget_frag");

    //dynamic state
    vk::DynamicState DynamicState[2]={vk::DynamicState::eViewport,vk::DynamicState::eScissor};

    vk::PipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo=vk::PipelineDynamicStateCreateInfo()
        .setDynamicStateCount(2)
        .setPDynamicStates(DynamicState);

    vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2];
    PipelineShaderStageCreateInfo[0]=vk::PipelineShaderStageCreateInfo()
        .setStage(vk::ShaderStageFlagBits::eVertex)
        .setModule(VertexShader->Module)
        .setPName("main");

    PipelineShaderStageCreateInfo[1]=vk::PipelineShaderStageCreateInfo()
        .setStage(vk::ShaderStageFlagBits::eFragment)
        .setModule(FragmentShader->Module)
        .setPName("main");

    vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
        .setVertexBindingDescriptionCount(0)
        .setVertexAttributeDescriptionCount(0);

    vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo
        =vk::PipelineInputAssemblyStateCreateInfo()
        .setTopology(vk::PrimitiveTopology::eTriangleStrip);
    
    vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
        .setViewportCount(1)
        .setScissorCount(1);

    vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
        .setPolygonMode(vk::PolygonMode::eFill)
        .setCullMode(vk::CullModeFlagBits::eNone)
        .setFrontFace(vk::FrontFace::eClockwise)
        .setLineWidth(1.0f);

    vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
        .setRasterizationSamples(vk::SampleCountFlagBits::e1);

    vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
        .setDepthTestEnable(true)
        .setDepthWriteEnable(true)
        .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
        .setDepthBoundsTestEnable(false)
        .setStencilTestEnable(false);

    vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
        
            .setColorWriteMask(
                vk::ColorComponentFlagBits::eR
                |vk::ColorComponentFlagBits::eG
                |vk::ColorComponentFlagBits::eB
                |vk::ColorComponentFlagBits::eA
            )
            .setBlendEnable(true) //color might be transparent
            .setSrcColorBlendFactor(vk::BlendFactor::eSrcAlpha)
            .setDstColorBlendFactor(vk::BlendFactor::eOneMinusSrcAlpha)
            .setColorBlendOp(vk::BlendOp::eAdd)
            .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
            .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
            .setAlphaBlendOp(vk::BlendOp::eAdd)
            ;

    vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
        .setAttachmentCount(1)
        .setPAttachments(&PipelineColorBlendAttachmentState);

    vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
        .setPDynamicState(&PipelineDynamicStateCreateInfo)
        .setStageCount(2)
        .setPStages(PipelineShaderStageCreateInfo)
        .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
        .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
        .setPViewportState(&PipelineViewportStateCreateInfo)
        .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
        .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
        .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
        .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
        .setLayout(CircleWidgetPipelineLayout)
        .setRenderPass(CVulkanContext::Get()->GetWidgetRenderPass())
        .setSubpass(0);
    
    CircleWidgetPipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;
}

void SWidgetPipelines::CreateRingWidgetPipeline()
{
    //create pipeline layout
    TVector<vk::PushConstantRange> PushConstantRanges=
    {
        vk::PushConstantRange()
        .setStageFlags(vk::ShaderStageFlagBits::eVertex)
        .setOffset(0)
        .setSize(sizeof(SRingWidgetVertexPushConstant))
    };

    TVector<vk::DescriptorSetLayout> PipelineDesLayouts={CVulkanContext::Get()->GetImageWidgetDescriptorSetLayout().Layout};
    vk::PipelineLayoutCreateInfo PipelineLayoutCreateInfo = vk::PipelineLayoutCreateInfo()
        .setSetLayouts(PipelineDesLayouts)
        .setPushConstantRanges(PushConstantRanges);
    

    RingWidgetPipelineLayout =CVulkanContext::Get()->GetDevice().createPipelineLayout(PipelineLayoutCreateInfo);

    //create pipeline
    auto VertexShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"RingWidget_vert");
    auto FragmentShader= CVulkanContext::Get()->GetShaderManager()->GetVulkanOnlyShader(U"RingWidget_frag");

    //dynamic state
    vk::DynamicState DynamicState[2]={vk::DynamicState::eViewport,vk::DynamicState::eScissor};

    vk::PipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo=vk::PipelineDynamicStateCreateInfo()
        .setDynamicStateCount(2)
        .setPDynamicStates(DynamicState);

    vk::PipelineShaderStageCreateInfo PipelineShaderStageCreateInfo[2];
    PipelineShaderStageCreateInfo[0]=vk::PipelineShaderStageCreateInfo()
        .setStage(vk::ShaderStageFlagBits::eVertex)
        .setModule(VertexShader->Module)
        .setPName("main");

    PipelineShaderStageCreateInfo[1]=vk::PipelineShaderStageCreateInfo()
        .setStage(vk::ShaderStageFlagBits::eFragment)
        .setModule(FragmentShader->Module)
        .setPName("main");

    vk::PipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo=vk::PipelineVertexInputStateCreateInfo()
        .setVertexBindingDescriptionCount(0)
        .setVertexAttributeDescriptionCount(0);

    vk::PipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo
        =vk::PipelineInputAssemblyStateCreateInfo()
        .setTopology(vk::PrimitiveTopology::eTriangleStrip);

    vk::PipelineViewportStateCreateInfo PipelineViewportStateCreateInfo=vk::PipelineViewportStateCreateInfo()
        .setViewportCount(1)
        .setScissorCount(1);
    
    vk::PipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo=vk::PipelineRasterizationStateCreateInfo()
        .setPolygonMode(vk::PolygonMode::eFill)
        .setCullMode(vk::CullModeFlagBits::eNone)
        .setFrontFace(vk::FrontFace::eClockwise)
        .setLineWidth(1.0f);
    
    vk::PipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo=vk::PipelineMultisampleStateCreateInfo()
        .setRasterizationSamples(vk::SampleCountFlagBits::e1);

    vk::PipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo=vk::PipelineDepthStencilStateCreateInfo()
        .setDepthTestEnable(true)
        .setDepthWriteEnable(true)
        .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
        .setDepthBoundsTestEnable(false)
        .setStencilTestEnable(false);

    vk::PipelineColorBlendAttachmentState PipelineColorBlendAttachmentState=vk::PipelineColorBlendAttachmentState()
        
            .setColorWriteMask(
                vk::ColorComponentFlagBits::eR
                |vk::ColorComponentFlagBits::eG
                |vk::ColorComponentFlagBits::eB
                |vk::ColorComponentFlagBits::eA
            )
            .setBlendEnable(true) //color might be transparent
            .setSrcColorBlendFactor(vk::BlendFactor::eSrcAlpha)
            .setDstColorBlendFactor(vk::BlendFactor::eOneMinusSrcAlpha)
            .setColorBlendOp(vk::BlendOp::eAdd)
            .setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
            .setDstAlphaBlendFactor(vk::BlendFactor::eZero)
            .setAlphaBlendOp(vk::BlendOp::eAdd)
            ;

    vk::PipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo=vk::PipelineColorBlendStateCreateInfo()
        .setAttachmentCount(1)
        .setPAttachments(&PipelineColorBlendAttachmentState);

    vk::GraphicsPipelineCreateInfo GraphicsPipelineCreateInfo=vk::GraphicsPipelineCreateInfo()
        .setPDynamicState(&PipelineDynamicStateCreateInfo)
        .setStageCount(2)
        .setPStages(PipelineShaderStageCreateInfo)
        .setPVertexInputState(&PipelineVertexInputStateCreateInfo)
        .setPInputAssemblyState(&PipelineInputAssemblyStateCreateInfo)
        .setPViewportState(&PipelineViewportStateCreateInfo)
        .setPRasterizationState(&PipelineRasterizationStateCreateInfo)
        .setPMultisampleState(&PipelineMultisampleStateCreateInfo)
        .setPDepthStencilState(&PipelineDepthStencilStateCreateInfo)
        .setPColorBlendState(&PipelineColorBlendStateCreateInfo)
        .setLayout(RingWidgetPipelineLayout)
        .setRenderPass(CVulkanContext::Get()->GetWidgetRenderPass())
        .setSubpass(0);

    RingWidgetPipeline=CVulkanContext::Get()->GetDevice().createGraphicsPipeline(nullptr,GraphicsPipelineCreateInfo).value;
}
